package slice

func Delete[T any](sli []T, idx int) []T {
	if idx < 0 || idx >= len(sli) {
		return sli
	}

	//delete肯定不会扩容, 所以append与copy性能差不多吧?
	//return append(sli[:idx], sli[idx+1:]...)

	copy(sli[idx:], sli[idx+1:])
	sli = sli[:len(sli)-1]
	return shrinkCapacity(sli)
}

func shrinkCapacity[T any](sli []T) []T {
	if ok, newCap := needShrink(len(sli), cap(sli)); ok {
		newSli := make([]T, 0, newCap)
		newSli = append(newSli, sli...)
		return newSli
	}
	return sli
}

// 正向扩容的逆操作
func needShrink(len, cap int) (needShrink bool, newCap int) {
	if cap <= 64 {
		return false, cap
	}

	var rate float64
	const threshold = 256
	if cap <= threshold {
		rate = 2 //缩容至:cap为len的2倍
	} else {
		if len <= threshold {
			rate = 2 //缩容至:cap为len的2倍
		} else {
			rate = 1.25 //缩容至:cap为len的1.25倍
		}
	}

	//一次性缩容到最合适的newCap
	newCap = int(float64(len) * rate)
	if newCap < cap {
		return true, newCap
	}
	return false, cap
}
